# ==============================================================================
# SCRIPT 01: PROCESSAMENTO DE DADOS (2022)
# ==============================================================================

# ------------------------------------------------------------------------------
# 1. OBJETIVO
# ------------------------------------------------------------------------------
# Este script realiza o pré-processamento completo dos dados de 2022, incluindo:
# - Carregamento dos dados brutos (DAIR e ISP)
# - Limpeza e padronização
# - Cálculo dos percentuais de alocação por RPPS
# - Cruzamento das bases de dados
# - Geração de uma base de dados final e limpa para a análise de clusterização

# ------------------------------------------------------------------------------
# 2. BIBLIOTECAS NECESSÁRIAS
# ------------------------------------------------------------------------------
import pandas as pd
import numpy as np
import warnings

warnings.filterwarnings("ignore")

# ------------------------------------------------------------------------------
# 3. FUNÇÕES AUXILIARES
# ------------------------------------------------------------------------------

# Função para converter números em formato brasileiro (ex: "1.234,56") para float
def converter_numero_brasileiro(valor):
    """Converte uma string numérica em formato brasileiro para float."""
    if isinstance(valor, str):
        # Remove pontos de milhar e substitui vírgula decimal por ponto
        valor = valor.replace(".", "").replace(",", ".")
    try:
        # Tenta converter para float
        return float(valor)
    except (ValueError, TypeError):
        # Retorna NaN se a conversão falhar
        return np.nan

# ------------------------------------------------------------------------------
# 4. CONFIGURAÇÕES E CONSTANTES
# ------------------------------------------------------------------------------

# Caminhos dos arquivos de entrada
DAIR_PATH = "../2022_data/dados_dair_2022.csv"
ISP_PATH = "../2022_data/dados_isp_2022.xlsx"

# Caminho do arquivo de saída
OUTPUT_PATH = "../2022_data/base_final_2022.csv"

# Lista de segmentos de investimento a serem considerados
SEGMENTOS = [
    "Renda Fixa", "Renda Variável", "Investimentos no Exterior",
    "Investimentos Estruturados", "Fundos Imobiliários",
    "Empréstimos Consignados", "Disponibilidades Financeiras"
]

# Lista de erros manifestos a serem excluídos (RPPS com dados inconsistentes)
ERROS_MANIFESTOS = ["URUCARÁ", "FILADÉLFIA"]

# ------------------------------------------------------------------------------
# 5. EXECUÇÃO DO SCRIPT
# ------------------------------------------------------------------------------

print("="*80)
print("INICIANDO PROCESSAMENTO DE DADOS - 2022")
print("="*80)

# --- 5.1. Carregamento e Limpeza dos Dados do DAIR ---
print("\n1. Carregando e limpando dados do DAIR...")

# Carregar dados do DAIR com encoding apropriado e separador
df_dair = pd.read_csv(DAIR_PATH, sep=";", encoding="utf-8-sig", dtype=str)
print(f"  - {len(df_dair)} registros carregados do DAIR.")

# Renomear colunas para facilitar o acesso
df_dair.rename(columns={
    "CNPJ": "CNPJ",
    "Competência": "Competência",
    "Segmento": "Segmento",
    "Valor Total Atual": "Valor"
}, inplace=True)

# Converter a coluna "Valor" para formato numérico
df_dair["Valor"] = df_dair["Valor"].apply(converter_numero_brasileiro)

# Filtrar apenas os segmentos de interesse
df_dair = df_dair[df_dair["Segmento"].isin(SEGMENTOS)]
print(f"  - {len(df_dair)} registros após filtrar segmentos de interesse.")

# Remover registros com valores nulos ou negativos
df_dair.dropna(subset=["Valor"], inplace=True)
df_dair = df_dair[df_dair["Valor"] >= 0]
print(f"  - {len(df_dair)} registros após remover valores nulos/negativos.")

# --- 5.2. Cálculo dos Percentuais de Alocação ---
print("\n2. Calculando percentuais de alocação...")

# Agrupar por CNPJ e Competência para calcular o valor total por RPPS/mês
df_dair["Valor_Total_RPPS_Mes"] = df_dair.groupby(["CNPJ", "Competência"])["Valor"].transform("sum")

# Calcular o percentual de alocação para cada segmento
df_dair["Percentual"] = (df_dair["Valor"] / df_dair["Valor_Total_RPPS_Mes"]) * 100

# Substituir NaN por 0 (casos onde o valor total é zero)
df_dair["Percentual"].fillna(0, inplace=True)

# # Filtrar apenas os dados de Dezembro de 2022
df_dair_dez = df_dair[df_dair["Competência"] == "122022"].copy()
num_rpps_dez = len(df_dair_dez['CNPJ'].unique())
print(f"  - {num_rpps_dez} RPPS encontrados em Dezembro de 2022.")

# Pivotar a tabela para ter segmentos como colunas
df_pivot = df_dair_dez.pivot_table(
    index="CNPJ",
    columns="Segmento",
    values="Percentual",
    aggfunc="sum"
).fillna(0)

# Resetar o índice para transformar CNPJ em uma coluna
df_pivot.reset_index(inplace=True)
print(f"  - Base de dados pivotada com {len(df_pivot)} RPPS.")

# --- 5.3. Carregamento e Limpeza dos Dados do ISP ---
print("\n3. Carregando e limpando dados do ISP...")

# Carregar dados do ISP
df_isp = pd.read_excel(ISP_PATH, dtype=str)
print(f"  - {len(df_isp)} registros carregados do ISP.")

# Renomear colunas
df_isp.rename(columns={
    "CNPJ": "CNPJ",
    "ENTE": "ENTE",
    "UF": "UF",
    "REGIÃO": "REGIÃO",
    "CLASSIFICAÇÃO": "IAR_CLASSIFICACAO",
    "PONTUAÇÃO": "IAR_PONTUACAO"
}, inplace=True)

# Converter pontuação do IAR para numérico
df_isp["IAR_PONTUACAO"] = pd.to_numeric(df_isp["IAR_PONTUACAO"], errors="coerce")

# Padronizar CNPJ para cruzamento (remover pontuação)
df_isp["CNPJ"] = df_isp["CNPJ"].str.replace(r"[./-]+", "", regex=True).str.zfill(14)
df_pivot["CNPJ"] = df_pivot["CNPJ"].str.replace(r"[./-]+", "", regex=True).str.zfill(14)

# --- 5.4. Cruzamento das Bases de Dados ---
print("\n4. Cruzando bases de dados DAIR e ISP...")

# Realizar o merge (inner join) para manter apenas RPPS presentes em ambas as bases
df_final = pd.merge(df_pivot, df_isp, on="CNPJ", how="inner")
print(f"  - {len(df_final)} RPPS após cruzamento das bases.")

# --- 5.5. Limpeza Final ---
print("\n5. Realizando limpeza final...")

# Padronizar nome do ENTE para exclusão de erros
df_final["ENTE_PADRAO"] = df_final["ENTE"].str.strip().str.upper()

# Excluir erros manifestos
antes_exclusao = len(df_final)
df_final = df_final[~df_final["ENTE_PADRAO"].str.contains("|".join(ERROS_MANIFESTOS), na=False)]
depois_exclusao = len(df_final)
print(f"  - {antes_exclusao - depois_exclusao} RPPS (erros manifestos) excluídos.")
print(f"  - Amostra final: {depois_exclusao} RPPS.")

# Selecionar e ordenar colunas finais
colunas_finais = ["CNPJ", "ENTE", "UF", "REGIÃO", "IAR_CLASSIFICACAO", "IAR_PONTUACAO"] + SEGMENTOS
df_final = df_final[colunas_finais]

# --- 5.6. Salvando a Base Final ---
print(f"\n6. Salvando base de dados final em: {OUTPUT_PATH}")
df_final.to_csv(OUTPUT_PATH, index=False)

print("\n" + "="*80)
print("PROCESSAMENTO DE DADOS DE 2022 CONCLUÍDO COM SUCESSO!")
print("="*80)
